package sk.stuba.fiit.repka.dp.owl.gui;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;

import sk.stuba.fiit.repka.dp.owl.MyOWLIndividual;
import sk.stuba.fiit.repka.dp.owl.MyOWLObjectProperty;
import sk.stuba.fiit.repka.dp.owl.ObjPropIndiAssociation;

public class AddObjectToIndividualDialog extends JDialog implements ActionListener {

	private final JPanel contentPanel = new JPanel();
	
	private List<MyOWLObjectProperty> objProperties;
	private List<MyOWLIndividual> individuals;
	
	private Map<JRadioButton, MyOWLIndividual> individualsMapper;
	private Map<JRadioButton, MyOWLObjectProperty> objPropMapper;
	private ButtonGroup groupOfIndi;
	private ButtonGroup groupOfObjProp;
	
	
	private ObjPropIndiAssociation output;
	
	public ObjPropIndiAssociation getOutput() {
		return output;
	}

	/**
	 * Create the dialog.
	 */
	public AddObjectToIndividualDialog(List<MyOWLObjectProperty> objProperties, List<MyOWLIndividual> individuals) {
		this.objProperties = objProperties;
		this.individuals = individuals;
		this.individualsMapper = new HashMap<JRadioButton, MyOWLIndividual>();
		this.objPropMapper = new HashMap<JRadioButton, MyOWLObjectProperty>();
		
		this.setModal(true);
		setTitle("Add Object Property To Individual");
		setBounds(100, 100, 450, 300);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		contentPanel.setLayout(new GridLayout(1, 0, 0, 0));
		
		JPanel objPropPanel = new JPanel();
		objPropPanel.setBorder(new TitledBorder(null, "Object Properties", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		objPropPanel.setLayout(new GridLayout(0,1));
		contentPanel.add(objPropPanel);
		
		JPanel individualPanel = new JPanel();
		individualPanel.setBorder(new TitledBorder(null, "Individuals",	TitledBorder.LEADING, TitledBorder.TOP, null, null));
		individualPanel.setLayout(new GridLayout(0,1));
		contentPanel.add(individualPanel);
		
		JScrollPane objPropSP = new JScrollPane();
		objPropSP.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		objPropSP.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		objPropSP.setViewportView(objPropPanel);
		contentPanel.add(objPropSP);
		
		JScrollPane individualsSP = new JScrollPane();
		individualsSP.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		individualsSP.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		individualsSP.setViewportView(individualPanel);
		contentPanel.add(individualsSP);
		
		//generate JRadionButtons
		this.groupOfIndi = this.generateRadioButtons(individualPanel, this.individuals);
		this.groupOfObjProp = this.generateRadioButtons(objPropPanel, this.objProperties);
		
		JPanel buttonPane = new JPanel();
		buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
		getContentPane().add(buttonPane, BorderLayout.SOUTH);
		{
			JButton okButton = new JButton("OK");
			okButton.setActionCommand("OK");
			okButton.addActionListener(this);
			buttonPane.add(okButton);
			getRootPane().setDefaultButton(okButton);
		}
		{
			JButton cancelButton = new JButton("Cancel");
			cancelButton.setActionCommand("Cancel");
			cancelButton.addActionListener(this);
			buttonPane.add(cancelButton);
		}
		this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		this.setVisible(true);
	}
	
	//method generates JRadionButtons
	private ButtonGroup generateRadioButtons(JPanel panel, List<? extends Object> list) {
		ButtonGroup group = new ButtonGroup();
		Iterator<? extends Object> iter = list.iterator();
		while(iter.hasNext()) {
			Object o = iter.next();
			if(o instanceof MyOWLIndividual) {
				JRadioButton bt = new JRadioButton(((MyOWLIndividual)o).getName());
				this.individualsMapper.put(bt, (MyOWLIndividual)o); //map button to owlindividual
				panel.add(bt);
				group.add(bt);
			} else if(o instanceof MyOWLObjectProperty) {
				JRadioButton bt = new JRadioButton(((MyOWLObjectProperty)o).getName());
				this.objPropMapper.put(bt, (MyOWLObjectProperty)o); //map button to object property
				panel.add(bt);
				group.add(bt);
			}
		}
		return group;
	}
	
	//map object prop to individual - set output
	private void mapObjToIndi(JRadioButton selectedIndiBT, JRadioButton selectedObjBT) {
		MyOWLIndividual i = this.individualsMapper.remove(selectedIndiBT);
		MyOWLObjectProperty o = this.objPropMapper.remove(selectedObjBT);
		this.output = new ObjPropIndiAssociation(o, i);
	}
	
	// return selected radio button from group of radio buttons
	private JRadioButton getSelection(ButtonGroup group) {
		for (Enumeration e = group.getElements(); e.hasMoreElements();) {
			JRadioButton b = (JRadioButton) e.nextElement();
			if (b.getModel() == group.getSelection()) {
				return b;
			}
		}
		return null;
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		if("OK".equals(e.getActionCommand())) {
			Toolkit toolkit = Toolkit.getDefaultToolkit();
			JRadioButton selectedIndiBT = getSelection(this.groupOfIndi);
			JRadioButton selectedObjPropBT = getSelection(this.groupOfObjProp);
			if(selectedIndiBT != null && selectedObjPropBT != null) {
				this.mapObjToIndi(selectedIndiBT, selectedObjPropBT);
				this.dispose();
			} else {
				toolkit.beep();
			}
		} else if("Cancel".equals(e.getActionCommand())) {
			this.dispose();
		}
		
	}

}
